package com.dareway.threadPoll;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class test {
    public static void main(String[] args) throws InterruptedException {
        //**CPU密集型：** CPU 核心数 = 最大同时执行线程数
        //**IO密集型：** CPU 核心数 = CPU核心数的2倍
        ThreadPoolExecutor executor =
                new ThreadPoolExecutor(2, 4,   //2个核心线程，最大线程数为4个
                        3, TimeUnit.SECONDS,        //最大空闲时间为3秒钟
                        new ArrayBlockingQueue<>(2),
                        new ThreadPoolExecutor.AbortPolicy());     //这里使用容量为2的ArrayBlockingQueue队列
//        AbortPolicy(默认)：像上面一样，直接抛异常。
//        CallerRunsPolicy：直接让提交任务的线程运行这个任务，比如在主线程向线程池提交了任务，那么就直接由主线程执行。
//        DiscardOldestPolicy：丢弃队列中最近的一个任务，替换为当前任务。
//        DiscardPolicy：什么也不用做。
        for (int i = 0; i < 5; i++) {   //开始6个任务
            int finalI = i;
            executor.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 开始执行！（" + finalI);
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(Thread.currentThread().getName() + " 已结束！（" + finalI);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.execute(() -> {
            System.out.println(Thread.currentThread().getName() + " 开始执行！");
            throw new RuntimeException("error");
        });
        TimeUnit.SECONDS.sleep(1);
        executor.execute(() -> {
            System.out.println("线程池中线程数量：" + executor.getPoolSize());
            System.out.println(Thread.currentThread().getName());
        });
        TimeUnit.SECONDS.sleep(1);    //看看当前线程池中的线程数量
        System.out.println("线程池中线程数量：" + executor.getPoolSize());
        TimeUnit.SECONDS.sleep(5);     //等到超过空闲时间
        System.out.println("线程池中线程数量：" + executor.getPoolSize());

        executor.shutdownNow();    //使用完线程池记得关闭，不然程序不会结束，它会取消所有等待中的任务以及试图中断正在执行的任务，关闭后，无法再提交任务，一律拒绝
        //executor.shutdown();     同样可以关闭，但是会执行完等待队列中的任务再关闭
    }
}
